﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using db;
using System.Collections.ObjectModel;

namespace dominio
{
    public class Sistema : IObservable<Object>
    {
        private static Sistema _instance = null;
        private ObservableCollection<Deposito> _depositos;
        private ObservableCollection<Remito> _remitos;
        private List<IObserver<Object>> _listaObservadores = new List<IObserver<Object>>();

        //Constructor
        protected Sistema()
        {
            _depositos = Datos.getInstance().GetDepositos();
        }

        public static Sistema getInstance()
        {
            if (_instance == null)
            {
                _instance = new Sistema();
            }
            return _instance;
        }
        public ObservableCollection<Deposito> Depositos
        {
            get { return _depositos; }
            set
            {
                _depositos = value;

            }
        }
        public Deposito GetDepositoActual()
        {
            return Datos.getInstance().GetDepositoActual();
        }
        public ObservableCollection<Remito> getRemitosSector(Sector s)
        {
            //if (_remitos == null && _remitos[0] != null || _remitos[0].Sector != s)
               _remitos = Datos.getInstance().getRemitosSector(s);
            
            return _remitos;
            
           
        }

        public ObservableCollection<Remito> getRemitosSectorFecha(Sector s, DateTime ini, DateTime fin)
        {
            //if (_remitos == null && _remitos[0] != null || _remitos[0].Sector != s)
            _remitos = Datos.getInstance().getRemitosSectorFecha(s,ini,fin);

            return _remitos;
        }

        public ObservableCollection<Remito> getRemitosFecha(DateTime ini, DateTime fin)
        {
            //if (_remitos == null && _remitos[0] != null || _remitos[0].Sector != s)
            _remitos = Datos.getInstance().getRemitosFecha(ini, fin);

            return _remitos;
        }


        public List<Proveedor> GetProveedores()
        {
            return Datos.getInstance().GetProveedores();
           
        }

        public void InsertarRemito(Remito r, int tipo) // 1: Entrada, -1: Salida
        {
            r.Peso *= tipo;
            if (Datos.getInstance().InsertarRemito(r))
            {
                _remitos.Add(r);
                Notify();
            }


        }



        #region IObservable<object> Members

        public IDisposable Subscribe(IObserver<object> observer)
        {
            if (!_listaObservadores.Contains(observer))
                _listaObservadores.Add(observer);
            return new Unsubscriber(_listaObservadores, observer);
        }

        #endregion

        private class Unsubscriber : IDisposable
        {
            private List<IObserver<Object>> _observers;
            private IObserver<Object> _observer;

            public Unsubscriber(List<IObserver<Object>> observers, IObserver<Object> observer)
            {
                this._observers = observers;
                this._observer = observer;
            }

            public void Dispose()
            {
                if (_observer != null && _observers.Contains(_observer))
                    _observers.Remove(_observer);
            }


        }

        private void Notify()
        {
            foreach (IObserver<Object> o in _listaObservadores)
            {
                o.OnNext(null);
            }
        }

        public void EstablecerDepositoActual(Deposito dActual)
        {
            Datos.getInstance().EstablecerDepositoActual(dActual);
            Notify();
        }
       

    }
}
